<!DOCTYPE html>
<html>

  <head>
    <meta charset='utf-8' />
    <meta http-equiv="X-UA-Compatible" content="chrome=1" />
    <meta name="description" content="CAS - Single Sign-On for the Web" />
    
    
    <link rel="stylesheet" type="text/css" media="screen"
          href="../../stylesheets/v40x-stylesheet.css">
    <link rel="stylesheet" type="text/css" media="print"
          href="../../stylesheets/print.css">
    <title>CAS - OpenID Protocol</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="../../javascripts/URI.js"></script>
    <script src="../../javascripts/v40x-main.js"></script>
  </head>

  <body>
    <!-- HEADER -->
    <div id="header_wrap" class="outer">
        <header class="inner">
          <a id="forkme_banner" href="https://github.com/Jasig/cas">View on GitHub</a>
          <div id="project_title">
            <a class="undecorated" href="../../index.html">
              <img class="undecorated" src="../../images/cas_logo.png"/>
            </a>
          </div>
          <h2 id="project_tagline">Single Sign-On for the Web</h2>
        </header>
    </div>

    <!-- NAVBAR -->    
    <div id="navbar_wrap" class="outer">
      <header id="navbar_content" class="inner">
        <div class="navlink">
  <a href="../../index.html">Home</a>
</div>
<div class="navlink">
  <a href="https://github.com/Jasig/cas/releases">Downloads</a>
</div>
<div class="navlink">
  <a href="https://www.google.com/cse/publicurl?cx=017040929083740828958:sqr2hwvrxmg">Search</a>
</div>
<div class="navlink">
  <a href="../../Support.html">Support</a>
</div>
<div class="navlink">
  <a href="../../Mailing-Lists.html">Mailing Lists</a>
</div>
<div class="navlink">
  <a href="../../Older-Versions.html">Older Versions</a>
</div>

        </header>
    </div>

      <!-- SIDEBAR -->
      <div id="sidebar_wrap" class="outer">
        <header id="sidebar_content" class="inner">
          <span id="sidebartoc"></span>
        </header >
      </div>
      
      <!-- PAGE TABLE OF CONTENTS -->
      <div id="table_contents" class="outer">
        <header id="sidebar_content" class="inner">
          <span id="tableOfContents"></span>
        </header>
      </div>
      
      <!-- MAIN CONTENT -->
      <div id="main_content_wrap" class="outer">
        <section id="main_content" class="inner">
          <h1 id="openid-protocol">OpenID Protocol</h1>
<p>OpenID is an open, decentralized, free framework for user-centric digital identity. Users represent themselves using URIs. For more information see the http://www.openid.net.</p>

<p>CAS supports both the “dumb” and “smart” modes of the OpenID protocol. Dumb mode acts in a similar fashion to the existing CAS protocol. The smart mode differs in that it establishes an association between the client and the openId provider (OP) at the begining. Thanks to that association and the key exchange done during association, information exchanged between the client and the provider are signed and verified using this key. There is no need for the final request (which is equivalent in CAS protocol to the ticket validation).</p>

<p>OpenID identifiers are URIs. The default mechanism in CAS support is an uri ending with the actual user login (ie. http://my.cas.server/openid/<em>myusername</em> where the actual user login is <em>myusername</em>). This is not recommended and you should think of a more elaborated way of providing URIs to your users.</p>

<p>Support is enabled by including the following dependency in the Maven WAR overlay:</p>

<pre><code>&lt;dependency&gt;
  &lt;groupId&gt;org.jasig.cas&lt;/groupId&gt;
  &lt;artifactId&gt;cas-server-support-openid&lt;/artifactId&gt;
  &lt;version&gt;${cas.version}&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>

<h2 id="configuration">Configuration</h2>

<h3 id="declare-the-openid-endpoint">Declare the OpenID endpoint</h3>

<p>The OpenID discovery endpoint should be enabled during the configuration process. In the <em>web.xml</em> file, the following mapping must be added:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;servlet-mapping&gt;</span>
  <span class="nt">&lt;servlet-name&gt;</span>cas<span class="nt">&lt;/servlet-name&gt;</span>
  <span class="nt">&lt;url-pattern&gt;</span>/openid/*<span class="nt">&lt;/url-pattern&gt;</span>
<span class="nt">&lt;/servlet-mapping&gt;</span>
</code></pre></div>

<p>In the <em>cas-servlet.xml</em> file, the following mapping and bean must be also added:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;handlerMappingC&quot;</span> <span class="na">class=</span><span class="s">&quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&quot;</span><span class="nt">&gt;</span>
  <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;mappings&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;props&gt;</span>
      <span class="nt">&lt;prop</span> <span class="na">key=</span><span class="s">&quot;/logout&quot;</span><span class="nt">&gt;</span>logoutController<span class="nt">&lt;/prop&gt;</span>
      ...
      <span class="nt">&lt;prop</span> <span class="na">key=</span><span class="s">&quot;/openid/*&quot;</span><span class="nt">&gt;</span>openIdProviderController<span class="nt">&lt;/prop&gt;</span>
      ... 


<span class="nt">&lt;bean</span>
    <span class="na">id=</span><span class="s">&quot;openIdProviderController&quot;</span>
    <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.web.OpenIdProviderController&quot;</span>
    <span class="na">p:loginUrl=</span><span class="s">&quot;${server.prefix}/login&quot;</span><span class="nt">/&gt;</span>
</code></pre></div>

<h3 id="add-the-openid-entry-in-the-unique-id-generator-map">Add the OpenID entry in the unique id generator map</h3>

<p>The OpenID entry should be added to the <em>uniqueIdGenerators.xml</em> file:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;util:map</span> <span class="na">id=</span><span class="s">&quot;uniqueIdGeneratorsMap&quot;</span><span class="nt">&gt;</span>
  ...
  <span class="nt">&lt;entry</span>
    <span class="na">key=</span><span class="s">&quot;org.jasig.cas.support.openid.authentication.principal.OpenIdService&quot;</span>
    <span class="na">value-ref=</span><span class="s">&quot;serviceTicketUniqueIdGenerator&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/util:map&gt;</span>
</code></pre></div>

<h3 id="update-the-webflow">Update the webflow</h3>

<p>CAS uses a spring webflow to describe the the authentication process. We need to change it a little bit to allow CAS to switch to OpenID authentication if it recognizes one. This is done in the <em>login-webflow.xml</em> file. After the on-start element just add these two blocks:</p>

<div class="highlight"><pre><code class="xml"><span class="c">&lt;!-- If the request contains a parameter called openid.mode and is not an association request, switch to openId. Otherwise, continue normal webflow. --&gt;</span>
<span class="nt">&lt;decision-state</span> <span class="na">id=</span><span class="s">&quot;selectFirstAction&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;if</span>
       <span class="na">test=</span><span class="s">&quot;externalContext.requestParameterMap[&#39;openid.mode&#39;] neq &#39;&#39;</span>
<span class="s">        &amp;amp;&amp;amp; externalContext.requestParameterMap[&#39;openid.mode&#39;] neq null</span>
<span class="s">        &amp;amp;&amp;amp; externalContext.requestParameterMap[&#39;openid.mode&#39;] neq &#39;associate&#39;&quot;</span>
       <span class="na">then=</span><span class="s">&quot;openIdSingleSignOnAction&quot;</span> <span class="na">else=</span><span class="s">&quot;ticketGrantingTicketExistsCheck&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/decision-state&gt;</span>
       
<span class="c">&lt;!-- The OpenID authentication action. If authentication is successful, send the ticket granting ticker. Otherwise, redirect to the login form. --&gt;</span>
<span class="nt">&lt;action-state</span> <span class="na">id=</span><span class="s">&quot;openIdSingleSignOnAction&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;evaluate</span> <span class="na">expression=</span><span class="s">&quot;openIdSingleSignOnAction&quot;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;transition</span> <span class="na">on=</span><span class="s">&quot;success&quot;</span> <span class="na">to=</span><span class="s">&quot;sendTicketGrantingTicket&quot;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;transition</span> <span class="na">on=</span><span class="s">&quot;error&quot;</span> <span class="na">to=</span><span class="s">&quot;viewLoginForm&quot;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;transition</span> <span class="na">on=</span><span class="s">&quot;warn&quot;</span> <span class="na">to=</span><span class="s">&quot;warn&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/action-state&gt;</span>
</code></pre></div>

<p>The openIdSingleSignOnAction is itself defined in the <em>cas-servlet.xml</em> file:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;openIdSingleSignOnAction&quot;</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.web.flow.OpenIdSingleSignOnAction&quot;</span>
      <span class="na">p:centralAuthenticationService-ref=</span><span class="s">&quot;centralAuthenticationService&quot;</span><span class="nt">/&gt;</span>
</code></pre></div>

<h3 id="enable-openid-in-the-authenticationmanager">Enable OpenID in the AuthenticationManager</h3>

<p>The authentication manager is the place where authentication takes place. We must provide it two elements needed for a successful OpenId authentication. The first thing to do is to detect the user name from the OpenID identifier. When your CAS server will work as an OP, users will authenticate with an OpenID identifier, looking like this : http://localhost:8080/cas/openid/<em>myusername</em>. Actually, in your users database, this users login is probably myusername. We must provide the CAS server with a way to extract the user principal from the credentials he provides us. This is the first thing we’ll do in this section: add an OpenIdCredentialsToPrincipalResolver to the authentication manager. The next thing to give CAS is a specialized authentication handler.<br />
Open the <em>deployerConfigContext.xml</em> file, and locate the authenticationManager bean definition. It has two properties containing beans. In the credentials to principal property, add this bean definition:</p>

<div class="highlight"><pre><code class="xml"><span class="c">&lt;!-- The openid credentials to principal resolver --&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.authentication.principal.OpenIdCredentialsToPrincipalResolver&quot;</span> <span class="nt">/&gt;</span>
</code></pre></div>

<p>Then, in the authentication handler property, add this bean definition:</p>

<div class="highlight"><pre><code class="xml"><span class="c">&lt;!-- The open id authentication handler --&gt;</span>
<span class="nt">&lt;bean</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.authentication.handler.support.OpenIdCredentialsAuthenticationHandler&quot;</span> <span class="na">p:ticketRegistry-ref=</span><span class="s">&quot;ticketRegistry&quot;</span> <span class="nt">/&gt;</span>
</code></pre></div>

<h3 id="adapt-the-spring-cas-servlet-configuration">Adapt the Spring CAS servlet configuration</h3>

<p>We now have to make CAS handle nicely the OpenID request he will be presented with. First, we’ll add a handler for the /login url, when called to validate a ticket (CAS is implementing the dumb OpenID mode, which means it does not create an association at the beginning of the authentication process. It must then check the received authentication success notification, which is done by one extra HTTP request at the end of the process). Anywhere in the <em>cas-servlet.xml</em> file, add this bean definition:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;handlerMappingOpendId&quot;</span>
      <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.web.support.OpenIdPostUrlHandlerMapping&quot;</span><span class="nt">&gt;</span>
    <span class="c">&lt;!-- Notice we set the order value to 2, which is the order of the flow handler mapping. We&#39;ll fix that just next.</span>
<span class="c">    The OpenIDPostUrlHandlerMapping MUST be called before the login webflow action is called, otherwise we will never be able to validate the authentication success. --&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;order&quot;</span> <span class="na">value=</span><span class="s">&quot;2&quot;</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;mappings&quot;</span><span class="nt">&gt;</span>
        <span class="nt">&lt;props&gt;</span>
            <span class="nt">&lt;prop</span> <span class="na">key=</span><span class="s">&quot;/login&quot;</span><span class="nt">&gt;</span>delegatingController<span class="nt">&lt;/prop&gt;</span>
        <span class="nt">&lt;/props&gt;</span>
    <span class="nt">&lt;/property&gt;</span>
<span class="nt">&lt;/bean&gt;</span>
</code></pre></div>

<p>As we gave the order of 2 to the OpenIdPostUrlHandlerMapping, we must modify the FlowHandlerMapping objects orders to give it an incremented value. The loginFlowHandlerMapping order is incremented from 2 to 3:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;loginFlowHandlerMapping&quot;</span> <span class="na">class=</span><span class="s">&quot;org.springframework.webflow.mvc.servlet.FlowHandlerMapping&quot;</span>
   <span class="na">p:flowRegistry-ref=</span><span class="s">&quot;loginFlowRegistry&quot;</span> <span class="na">p:order=</span><span class="s">&quot;3&quot;</span><span class="nt">&gt;</span>
   <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;interceptors&quot;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;ref</span> <span class="na">local=</span><span class="s">&quot;localeChangeInterceptor&quot;</span> <span class="nt">/&gt;</span>
   <span class="nt">&lt;/property&gt;</span>
<span class="nt">&lt;/bean&gt;</span>
</code></pre></div>

<p>And the logoutFlowHandlerMapping order is moved from 3 to 4:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;logoutFlowHandlerMapping&quot;</span> <span class="na">class=</span><span class="s">&quot;org.springframework.webflow.mvc.servlet.FlowHandlerMapping&quot;</span>
   <span class="na">p:flowRegistry-ref=</span><span class="s">&quot;logoutFlowRegistry&quot;</span> <span class="na">p:order=</span><span class="s">&quot;4&quot;</span><span class="nt">&gt;</span>
   <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;interceptors&quot;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;ref</span> <span class="na">local=</span><span class="s">&quot;localeChangeInterceptor&quot;</span> <span class="nt">/&gt;</span>
   <span class="nt">&lt;/property&gt;</span>
<span class="nt">&lt;/bean&gt;</span>
</code></pre></div>

<p>In the handlerMappingOpenId, we referenced a bean called delegatingController. this bean is a special controller, using the Delegate pattern, which delegates the processing of a request to the first controller of its delegates which says it can handle it. So now we’ll provide two delegate controllers. The first one is handling the Smart OpenId association, and the second process the authentication and ticket validation. Add this two beans in the file.
The Smart OpenId controller:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;smartOpenIdAssociationController&quot;</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.web.mvc.SmartOpenIdController&quot;</span>
     <span class="na">p:serverManager-ref=</span><span class="s">&quot;serverManager&quot;</span>
     <span class="na">p:successView=</span><span class="s">&quot;casOpenIdAssociationSuccessView&quot;</span> <span class="na">p:failureView=</span><span class="s">&quot;casOpenIdAssociationFailureView&quot;</span> <span class="nt">/&gt;</span>
</code></pre></div>

<p>The OpenID validation controller:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;openIdValidateController&quot;</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.web.ServiceValidateController&quot;</span>
       <span class="na">p:validationSpecificationClass=</span><span class="s">&quot;org.jasig.cas.validation.Cas20WithoutProxyingValidationSpecification&quot;</span>
       <span class="na">p:centralAuthenticationService-ref=</span><span class="s">&quot;centralAuthenticationService&quot;</span>
       <span class="na">p:proxyHandler-ref=</span><span class="s">&quot;proxy20Handler&quot;</span> <span class="na">p:argumentExtractor-ref=</span><span class="s">&quot;openIdArgumentExtractor&quot;</span>
       <span class="na">p:successView=</span><span class="s">&quot;casOpenIdServiceSuccessView&quot;</span> <span class="na">p:failureView=</span><span class="s">&quot;casOpenIdServiceFailureView&quot;</span> <span class="nt">/&gt;</span>
</code></pre></div>

<p>We are done with the delegates. Now we must create the Delegating controller itself, and give it a list of delegates referencing the two delegates we just defined. So add this definition:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;delegatingController&quot;</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.web.DelegatingController&quot;</span>
  <span class="na">p:delegates-ref=</span><span class="s">&quot;delegateControllers&quot;</span><span class="nt">/&gt;</span>
 
<span class="nt">&lt;util:list</span> <span class="na">id=</span><span class="s">&quot;delegateControllers&quot;</span><span class="nt">&gt;</span>
  <span class="nt">&lt;ref</span> <span class="na">bean=</span><span class="s">&quot;smartOpenIdAssociationController&quot;</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;ref</span> <span class="na">bean=</span><span class="s">&quot;openIdValidateController&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/util:list&gt;</span>
</code></pre></div>

<p>Don’t forget to include the <em>util</em> namespace if you don’t have it already!</p>

<h3 id="add-an-argument-extractor">Add an argument extractor</h3>

<p>We must tell cas how to extract the OpenID information from the authentication request (openid.mode, openid.sig, openid.assoc_handle…). This is done in the <em>argumentExtractorsConfiguration.xml</em> file, located in the <em>spring-configuration</em> directory. Add this bean into the file:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;openIdArgumentExtractor&quot;</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.support.openid.web.support.OpenIdArgumentExtractor&quot;</span> <span class="nt">/&gt;</span>
 
<span class="nt">&lt;util:list</span> <span class="na">id=</span><span class="s">&quot;argumentExtractors&quot;</span><span class="nt">&gt;</span>
   <span class="nt">&lt;ref</span> <span class="na">bean=</span><span class="s">&quot;casArgumentExtractor&quot;</span> <span class="nt">/&gt;</span>
   <span class="c">&lt;!-- The OpenId arguments extractor --&gt;</span>
   <span class="nt">&lt;ref</span> <span class="na">bean=</span><span class="s">&quot;openIdArgumentExtractor&quot;</span> <span class="nt">/&gt;</span>
   <span class="nt">&lt;ref</span> <span class="na">bean=</span><span class="s">&quot;samlArgumentExtractor&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/util:list&gt;</span>
</code></pre></div>

<h3 id="add-the-server-manager">Add the server manager</h3>

<p>Next we must provide a ServerManager, which is a class from the openid4java library, which allows us to handle the Diffie-Hellman algorithm used by the association process. In the <em>spring-configuration/applicationContext.xml</em> file, add this bean definition:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;serverManager&quot;</span> <span class="na">class=</span><span class="s">&quot;org.openid4java.server.ServerManager&quot;</span>
   <span class="na">p:oPEndpointUrl=</span><span class="s">&quot;{cas.securityContext.casProcessingFilterEntryPoint.loginUrl}&quot;</span>
   <span class="na">p:enforceRpId=</span><span class="s">&quot;false&quot;</span> <span class="nt">/&gt;</span>
</code></pre></div>

<p>And finally, we need an applicationContext provider in the <em>spring-configuration/applicationContext.xml</em> file again:</p>

<div class="highlight"><pre><code class="xml"><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;applicationContextProvider&quot;</span> <span class="na">class=</span><span class="s">&quot;org.jasig.cas.util.ApplicationContextProvider&quot;</span> <span class="nt">/&gt;</span>
</code></pre></div>

<hr />

<h1 id="or-delegate-the-authentication-to-an-openid-provider">Or delegate the authentication to an OpenID provider</h1>

<p>Using the OpenID protocol, the CAS server can also be configured to <a href="../integration/Delegate-Authentication.html">delegate the authentication</a> to an OpenID provider.</p>


        </section>
      </div>

    <!-- FOOTER  -->
    <div id="footer_wrap" class="outer">
      <footer class="inner">
        <p>CAS is supported by the <a href="http://www.apereo.org/">Apereo Foundation</a>.</p>
      </footer>
    </div>
  </body>
</html>
